import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
import copy

# 加载 Iris 数据集
iris = load_iris()
X = iris.data[:5, 0]  # 使用前五行的第一列数据（花萼长度）

# 等深度分箱
def Same_High(H, data=[]):
    data = np.array(data)
    Sort_index = np.argsort(data)
    Box = []
    Box_th = 0
    Lave_num = data.shape[0]
    i = 0
    Box.append([])
    while i < data.shape[0]:
        if Lave_num > H or Lave_num == H:
            for t in range(H):
                Box[Box_th].append(Sort_index[i])
                i += 1
        else:
            for t in range(Lave_num):
                Box[Box_th].append(Sort_index[i])
                i += 1
        Lave_num -= H
        Box.append([])
        Box_th += 1
    Box.pop()  # Remove the empty list at the end
    return Box

# 平均值平滑
def mean_smooth(index):
    smooth = copy.deepcopy(X)
    for box in index:
        values = [smooth[i] for i in box]
        mean = np.mean(values)
        for i in box:
            smooth[i] = mean
    return smooth

# 中位数平滑
def median_smooth(index):
    smooth = copy.deepcopy(X)
    for box in index:
        values = [smooth[i] for i in box]
        median = np.median(values)
        for i in box:
            smooth[i] = median
    return smooth

# 边界值平滑
def boundary_smooth(index):
    smooth = copy.deepcopy(X)
    for box in index:
        if len(box) > 3 or len(box) == 3:
            min_val = smooth[box[0]]
            max_val = smooth[box[-1]]
            for i in box[1:-1]:
                a = smooth[i] - min_val
                b = max_val - smooth[i]
                if a > b:
                    smooth[i] = max_val
                else:
                    smooth[i] = min_val
    return smooth

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

n = 4
index = Same_High(n, X)

x1 = range(0, len(X))
y_mean = mean_smooth(index)
x2 = range(0, len(X))
y_median = median_smooth(index)
x3 = range(0, len(X))
y_bound = boundary_smooth(index)
x4 = range(0, len(X))
y_data = X

plt.figure()
plt.plot(x4, y_data, label='原始数据', linewidth=2, color='k', marker='^')
plt.plot(x1, y_mean, label='均值平滑', linewidth=3, color='k', linestyle=':', marker='o')
plt.plot(x2, y_median, label='中值平滑', linewidth=3, color='k', linestyle='--', marker='.')
plt.plot(x3, y_bound, label='边界值平滑', linewidth=3, color='blue', linestyle='-.', markerfacecolor='k', markersize=12)

plt.xlabel('序列')
plt.ylabel('数值')
plt.title('平滑前后对比')
plt.legend()
plt.show()